/**
 * 
 */
package us.gaaoc.framework.webapp.backingbeans.agent;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIParameter;
import javax.faces.component.UISelectOne;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.myfaces.custom.fileupload.UploadedFile;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.jfree.util.Log;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.transaction.annotation.Transactional;

import us.gaaoc.framework.businessmodel.Filing;
import us.gaaoc.framework.dao.ModelFacade;
import us.gaaoc.framework.dao.persistenceLogic.PersistInfoIntoCaseRecord;
import us.gaaoc.framework.model.Address;
import us.gaaoc.framework.model.CaseRecord;
import us.gaaoc.framework.model.CaseRecordStatus;
import us.gaaoc.framework.model.CaseRecordType;
import us.gaaoc.framework.model.Court;
import us.gaaoc.framework.model.DocPageRange;
import us.gaaoc.framework.model.DocumentInstance;
import us.gaaoc.framework.model.DocumentPackage;
import us.gaaoc.framework.model.DocumentStatus;
import us.gaaoc.framework.model.Documents;
import us.gaaoc.framework.model.LegalPreparer;
import us.gaaoc.framework.model.LocalCaseCategory;
import us.gaaoc.framework.model.LocalCaseDivision;
import us.gaaoc.framework.model.LocalCaseFilingType;
import us.gaaoc.framework.model.LocalCaseType;
import us.gaaoc.framework.model.Organizations;
import us.gaaoc.framework.model.Person;
import us.gaaoc.framework.model.PersonAddress;
import us.gaaoc.framework.model.PersonOrganizations;
import us.gaaoc.framework.model.PersonParticipants;
import us.gaaoc.framework.model.constants.Constants;
import us.gaaoc.framework.util.DateUtil;
import us.gaaoc.framework.util.LocalCaseInformation;
import us.gaaoc.framework.util.ValidatingTextFile;
import us.gaaoc.framework.util.io.FileUtility;
import us.gaaoc.framework.util.pdf.Concatenate;
import us.gaaoc.framework.util.pdf.PageRangesFromTextTargetsUtility;
import us.gaaoc.framework.util.pdf.SplitPDF;
import us.gaaoc.framework.webapp.backingbeans.BaseBackingBean;
import us.gaaoc.framework.webapp.util.UploadPackageException;
import us.gaaoc.framework.webapp.util.UploadPackageUtility;

/**
 * @author Sukahda Tapshalkar Mar 26, 2007
 * 
 */
@SuppressWarnings({"unchecked", "unused"})
public class FilingDocumentUploadPage extends BaseBackingBean {

	/**
	 * 
	 */
	private static final long serialVersionUID = -60848976107909141L;

	/**
	 * Properties
	 */
	private CaseRecord cr;

	private Date courtDate;

	private DataModel personModel;

	private DataModel documentsModel;

	private UploadedFile myFile;

	private List<UploadedFile> myFilesList = null;

	private List<Documents> documentList = new ArrayList<Documents>();

	private List<Documents> newUploadedDocumentList = new ArrayList<Documents>();

	private Filing filing;

	private List<Documents> uploadedDocumentList;

	private DataModel myFilesModel;

	private DataModel establishmentFilingModel;

	private UISelectOne docTypeInput;

	private ArrayList<SelectItem> docTypeDescriptionsItems = new ArrayList<SelectItem>();

	private boolean renderReviewBtn;

	private String docType;

	private UIParameter documentClicked;

	private UIParameter caseDetailsPage;

	private boolean renderListOfPersonsBtn;

	private List<Person> personsExtractedFromTextList = new ArrayList<Person>();

	private Person cusPerson;

	private PersonAddress cusPersonAddress;
	private Address cusAddress;

	private Person nonCusPerson;

	private PersonAddress nonCusPersonAddress;
	private Address nonCusAddress;

	private List<Person> initiatingPartyPersonsList = new ArrayList<Person>();

	private List<PersonAddress> initiatingPartyPersonAddresses = new ArrayList<PersonAddress>();

	//for uploading packages
	private String packageType;
	private UISelectOne packageTypeInput;
	private ArrayList<SelectItem> packageTypeDescriptionsItems = new ArrayList<SelectItem>();
	private UploadedFile packageDoc;
	private Court court;

	//to capture the local system's tracking of defendants
	private String externalCaseRecordNumber;

	//to capture the social security numbers and the dates of birth for 
	//checking for duplicate persons
	private String cusSSN;

	private String nonCusSSN;

	private List<String> initiatingPartyPersonSSNList;
	
	private Transaction transaction;
	private Session hbSession;
	/** A flag indicating that prevents more than one upload happening at once. */
	//private static boolean lockUploadProcess;
	
	private String courtUuid;
	
	private boolean asExhibit;

	/**
	 * Boolean to render the text box for inputting the civil action number.
	 * Fulton uses this
	 */
	private boolean contempt;
	
	/**
	 * String to hold the civil action number that is input
	 */
	private String cvNumber;

	/**
	 * Integer to hold the external case category code.
	 * <p>
	 * External Case Category Codes: <br/> 1 = Establishment, OCSS <br/> 2 =
	 * Contempt, OCSS <br/> 3 = Review/Modification, OCSS <br/> 4 = Motion to
	 * Redirect, OCSS <br/> 5 = Motion to Transfer, OCSS <br/> 6 = Registration,
	 * OCSS <br/>
	 * </p>
	 */
	int externalCaseCategoryCode = 0;

	private static final Logger LOG = Logger
			.getLogger(FilingDocumentUploadPage.class);

	/**
	 * Constructor
	 * 
	 * Session map input:
	 * 	caseUuid - the Case record to act upon. Can be null.
	 *  courtUuid - the uuid of the Court we are currently in. Can't be null.
	 *  externalCaseCategoryCode - The case category. Can't be null.
	 *  court - the court object we are currently filing in. Can't be null.
	 * Session map output:
	 *  -
	 */
	public FilingDocumentUploadPage() 
	{	
		init();
		
	}
	
	protected void init()
	{
		Map sessionMap = this.getFacesContext().getExternalContext()
		.getSessionMap();
		


		String crUuid = (String) sessionMap.get("caseUuid");
		courtUuid = (String) sessionMap.get("courtUuid");
		//Court courtFromSession = this.getModelFacade().findCourt(courtUuid);
		Court courtFromSession = (Court)this.getFacesContext().getExternalContext().getSessionMap().get("court");
		this.setCourt(courtFromSession);

		
		//boolean commit = false;
		//if(!HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().isActive()) 
		//{
		//	HibernatePhaseListener.getSessionFactory().getCurrentSession().beginTransaction();
		//	commit = true;
		//}
		
		/*
		 * TODO If existing case, pull external case category code from
		 * database. If new case, pull case category code from parameter set on
		 * new filing page in session.
		 */
		/***********************************************************************
		 * External Case Category Codes: 1 = Establishment, OCSS 2 = Contempt,
		 * OCSS 3 = Review/Modification, OCSS 4 = Motion to Redirect, OCSS 5 =
		 * Motion to Transfer, OCSS 6 = Registration, OCSS
		 * ********************************************************************
		 */
		
		
		try {
			//externalCaseCategoryCode = (Integer) sessionMap.get("externalCaseCategoryCode");
			externalCaseCategoryCode=2;
		}catch(NullPointerException exn)
		{
			FacesContext facesContext = this.getFacesContext();
			facesContext.addMessage("uploadForm:uploadFile",
					new FacesMessage(" There is no case category"));
		}
		if (crUuid != null) {
			this.setRenderReviewBtn(true);
			this.setRenderListOfPersonsBtn(true);
			this.setCr(this.getModelFacade().findCaseRecordById(crUuid, courtUuid));
		} else {
			this.setRenderReviewBtn(false);
			this.setRenderListOfPersonsBtn(false);
		}
		
		// This is for Fulton. This checks to see if it is a contempt.
		// If it is, then it will render the text box to enter the CV number of the case
		cvNumber = "";
		if(externalCaseCategoryCode == 2 && courtUuid.equalsIgnoreCase("courtUuid4")) {
			contempt = true;
		}
		else
			contempt = false;
		
		
		
	}
	
	/**
	 * @return the docType
	 */
	public String getDocType() {
		return docType;
	}

	/**
	 * @param docType
	 *            the docType to set
	 */
	public void setDocType(String docType) {
		this.docType = docType;
	}

	public UISelectOne getDocTypeInput() {
		return docTypeInput;
	}

	public void setDocTypeInput(UISelectOne docTypeInput) {
		this.docTypeInput = docTypeInput;
	}

	/**
	 * @return docTypeDescriptionsItems
	 */
	public ArrayList<SelectItem> getDocTypeDescriptionsItems() {
		// Initialize Array List if null
		if (docTypeDescriptionsItems == null) {
			docTypeDescriptionsItems = new ArrayList<SelectItem>();
		}
		docTypeDescriptionsItems.clear();
		this.docTypeDescriptionsItems.add(0,new SelectItem(""));
		List<DocumentInstance> docTypeList = this.getModelFacade()
				.findDocumentInstanceByAliasType(court);
		int i = docTypeList.size();
		DocumentInstance dt;
		for (int j = 0; j < i; j++) {
			dt = docTypeList.get(j);
			docTypeDescriptionsItems.add(new SelectItem(new Integer(dt
					.getCode()).toString(), dt.getDescription()));
		}
	
		return docTypeDescriptionsItems;
	}

	public void setDocTypDescriptionsItems(ArrayList<SelectItem> si) {
		docTypeDescriptionsItems = si;
	}

	/**
	 * @return myFilesModel
	 */
	public DataModel getMyFilesModel() {
		return myFilesModel;
	}

	/**
	 * @param set
	 *            myFilesModel
	 */
	public void setMyFilesModel(DataModel myFilesModel) {
		this.myFilesModel = myFilesModel;
	}

	/**
	 * @return myFilesList
	 */
	public List<UploadedFile> getMyFilesList() {
		return myFilesList;
	}

	/**
	 * @param set
	 *            myFile
	 */
	public void setMyFiles(List<UploadedFile> myFilesList) {
		this.myFilesList = myFilesList;
	}

	/**
	 * @return the myFile
	 */
	public UploadedFile getMyFile() {
		return myFile;
	}

	/**
	 * @param myFile
	 *            the myFile to set
	 */
	public void setMyFile(UploadedFile myFile) {
		this.myFile = myFile;
	}

	/**
	 * @return the courtDate
	 */
	public Date getCourtDate() {
		return courtDate;
	}

	/**
	 * @param courtDate
	 *            the courtDate to set
	 */
	public void setCourtDate(Date courtDate) {
		this.courtDate = courtDate;
	}

	/**
	 * @return documentList
	 */
	public List<Documents> getDocumentList() {
		return documentList;
	}

	/**
	 * @param set
	 *            DocumentTypesByAlias documentList
	 */
	public void setDocumentList(List<Documents> documentList) {
		this.documentList = documentList;
	}

	/**
	 * @return documentsModel
	 */
	public DataModel getDocumentsModel() {
		return documentsModel;
	}

	/**
	 * @param set
	 *            documentsModel
	 */
	public void setDocumentsModel(DataModel documentsModel) {
		this.documentsModel = documentsModel;
	}

	/**
	 * @return personModel
	 */
	public DataModel getPersonModel() {
		return personModel;
	}

	/**
	 * @param set
	 *            personModel
	 */
	public void setPersonModel(DataModel personModel) {
		this.personModel = personModel;
	}

	/**
	 * @return the documentClicked
	 */
	public UIParameter getDocumentClicked() {
		return documentClicked;
	}

	/**
	 * @param documentClicked
	 *            the documentClicked to set
	 */
	public void setDocumentClicked(UIParameter documentClicked) {
		this.documentClicked = documentClicked;
	}

	/**
	 * @return the packageType
	 */
	public String getPackageType() {
		return packageType;
	}

	/**
	 * @param packageType
	 *            the packageType to set
	 */
	public void setPackageType(String packageType) {
		this.packageType = packageType;
	}

	/**
	 * @return the packageTypeDescriptionsItems
	 */
	
	
	public ArrayList<SelectItem> getPackageTypeDescriptionsItems() {
		
		// Reinitialization of array to avoid duplicate additions to list.
		

		packageTypeDescriptionsItems = new ArrayList<SelectItem>();
		System.out.println("The Court ID now in process is" + court.getUuid());
		packageTypeDescriptionsItems.add(0,new SelectItem(""));
		if(court.getUuid().equalsIgnoreCase("courtUuidCoweta"))
		{
			List<DocumentPackage> packageTypeList = this.getModelFacade().findDocumentPackageByCaseRecordAction(court,this.getModelFacade().getCaseRecordActionsById(externalCaseCategoryCode));
			for (DocumentPackage dp : packageTypeList) {
				packageTypeDescriptionsItems.add(new SelectItem(dp.getUuid(), dp
						.getPackageName()));
				LOG.info("The package is .." + dp.getPackageName());
			}
			
			return packageTypeDescriptionsItems;
		}
		else
		{
			List<DocumentPackage> packageTypeList = this.getModelFacade().findDocumentPackageByAliasType(court);
			for (DocumentPackage dp : packageTypeList) {
				packageTypeDescriptionsItems.add(new SelectItem(dp.getUuid(), dp
						.getPackageName()));
				LOG.info("The package is .." + dp.getPackageName());
			}
			
			return packageTypeDescriptionsItems;
		}
		
		
	}
	
	
	/*
public ArrayList<SelectItem> getPackageTypeDescriptionsItems() {
		
		// Reinitialization of array to avoid duplicate additions to list.
		packageTypeDescriptionsItems = new ArrayList<SelectItem>();
		Log.info("The Court ID now in process is" + courtUuid);

		List<DocumentPackage> packageTypeList = this.getModelFacade().findDocumentPackageByCaseRecordAction(court,this.getModelFacade().getCaseRecordActionsById(externalCaseCategoryCode));
		for (DocumentPackage dp : packageTypeList) {
			packageTypeDescriptionsItems.add(new SelectItem(dp.getUuid(), dp
					.getPackageName()));
			LOG.info("The package is .." + dp.getPackageName());
		}
	
		return packageTypeDescriptionsItems;
	}
*/
	/**
	 * @param packageTypeDescriptionsItems
	 *            the packageTypeDescriptionsItems to set
	 */
	public void setPackageTypeDescriptionsItems(
			ArrayList<SelectItem> packageTypeDescriptionsItems) {
		this.packageTypeDescriptionsItems = packageTypeDescriptionsItems;
	}

	/**
	 * @return the packageTypeInput
	 */
	public UISelectOne getPackageTypeInput() {
		return packageTypeInput;
	}

	/**
	 * @param packageTypeInput
	 *            the packageTypeInput to set
	 */
	public void setPackageTypeInput(UISelectOne packageTypeInput) {
		this.packageTypeInput = packageTypeInput;
	}

	/**
	 * @return the packageDoc
	 */
	public UploadedFile getPackageDoc() {
		return packageDoc;
	}

	/**
	 * @param packageDoc
	 *            the packageDoc to set
	 */
	public void setPackageDoc(UploadedFile packageDoc) {
		this.packageDoc = packageDoc;
	}

	/**
	 * @return the court
	 */
	public Court getCourt() {
		return court;
	}

	/**
	 * @param court
	 *            the court to set
	 */
	public void setCourt(Court court) {
		this.court = court;
	}
	
	public String uploadFile() throws Exception{
				
		return uploadFileSafe();	
	}

	/**
	 * upload the document and create case record.
	 * 
	 * Session map input (for uploading DATA FILE)
	 * 	caseUuid - the case record. Can be null.
	 *  courtUuid - the court to file into. Can't Be null.
	 *  person - the person object that is filing. Can't be null.
	 *  externalCaseCategoryCode - the category of the case
	 * Session map input (for uploading document)
	 *  -
	 *  
	 * Object input (for DATA FILE)
	 *  myfile - the apache file upload object. 
	 * Object input (for Document)
	 *  docType - the string describing the document
	 *  
	 * 
	 * Session map output:
	 *  caseUuid - the case record uuid.
	 *  externalCaseRecordNumber - the OCSS number
	 *  
	 * @return
	 * @throws Exception
	 *             DocumentTypesByAlias
	 */
	public String uploadFileSafe() throws Exception {
		
		
		
		String returnStr = null;
		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		String caseRecordUuid = (String) sessionMap.get("caseUuid");
		String courtUuid = (String) sessionMap.get("courtUuid");
		Court court = null;
		Person filer = (Person) this.getFacesContext()
		.getExternalContext().getSessionMap().get("person");
		
		// TODO: confirm assumption that we only need the filer here if we are creating a new case. 
		if(filer == null && caseRecordUuid == null)
		{
			FacesContext facesContext = this.getFacesContext();
			facesContext.addMessage("uploadForm:uploadFile",
					new FacesMessage(" There is no user!"));
			return "failure";
		}
		
		
		if (caseRecordUuid != null)
		{
			this.setCr(this.getModelFacade().findCaseRecordById(caseRecordUuid, courtUuid));
			//court = this.getModelFacade().findCourtByUuid(this.getCr().getCourtUuid());
			court = this.getCourt();
		}else{
			if(courtUuid != null && court == null)
			{
				court = this.getModelFacade().findCourtByUuid(courtUuid);
			}else{
				FacesContext facesContext = this.getFacesContext();
				facesContext.addMessage("uploadForm:uploadFile",
						new FacesMessage(" There is no Case Filing and No Court!"));																		
				return "failure";
			}
		}
		
		
		
		
		if(contempt == true && courtUuid.equalsIgnoreCase("courtUuid4") && !cvNumber.equals("") && !isAsExhibit()){
			
			boolean exists = this.getModelFacade().findCivilActionNumber(cvNumber, courtUuid);
			
			if (exists) {
				LOG.info("Case already exists for the civil action number " + cvNumber);
				FacesContext facesContext = this.getFacesContext();
				facesContext.addMessage("uploadForm:uploadFile", new FacesMessage("Case already exists for the civil action number " + cvNumber));
				return "failure";
			}
		}

		byte[] fileBytes = myFile.getBytes();
		InputStream inStream = myFile.getInputStream();
		
		// case record already created
		if (caseRecordUuid != null) {			
						
			
			//this.setCr(this.getModelFacade().findCaseRecordById(caseRecordUuid, courtUuid));
			if (myFile.getContentType().equalsIgnoreCase("application/pdf")) {
				if (this.getDocType().equalsIgnoreCase("DATA FILE")) {
					LOG.info("Inside the checking of the title of the pdf..");
					FacesContext facesContext = this.getFacesContext();
					facesContext
							.addMessage(
									"uploadForm:uploadFile",
									new FacesMessage(
											"DATA FILE is not a title of a pdf's allowed for upload "));
					return "failure";
				}
				
				//SUCCESS
				this.getCr().setCaseRecordAction(this.getModelFacade().getCaseRecordActionsById(this.externalCaseCategoryCode));
				
				if(this.isAsExhibit())
				{
					Documents toAppend = null;
					boolean docExists = false;
					for(Documents d : this.getCr().getDocuments())
					{
						int docCode = d.getDocumentInstance().getCode();
						int docStatus = d.getStatus().getCode();
						if(docCode == Integer.parseInt(this.docType) 
								&& (d.getStatus().getCode() == 1 || d.getStatus().getCode() == 4 || d.getStatus().getCode() == 6))
						{
							toAppend = d;
							docExists = true;
							break;
						}
					}
					if(docExists)
					{
						File newFile = File.createTempFile(UUID.randomUUID().toString(),".pdf",
								new File("C:" + File.separator + "temp" + File.separator));
						FileOutputStream fw = new FileOutputStream(newFile);
						fw.write(fileBytes);
						fw.flush();
						fw.close();
						
						this.getModelFacade().addCaseRecordHistory(caseRecordUuid, Constants.CaseRecordEventType.FILING_CREATED_BY_LEGAL_PREPARER, filer,court.getUuid(), "Added Exhibit");
						cr.getFiler().add(filer);
						
						Concatenate concatenate = new Concatenate();
						concatenate.concatenateHelper(toAppend, newFile.getAbsolutePath());
						
						this.getModelFacade().getSession().saveOrUpdate(cr);	
						
						FacesContext facesContext = this.getFacesContext();
						facesContext.addMessage("uploadForm:uploadFile",
								new FacesMessage(" Appended exhibit to end of the document " + toAppend.getDocumentInstance().getDescription()));
						return "upload";
					}else{
						FacesContext facesContext = this.getFacesContext();
						facesContext.addMessage("uploadForm:uploadFile",
								new FacesMessage(" There is no document named $TITLE to add exhibit to.".replace("$TITLE",
										this.getModelFacade().findDocumentInstanceByCode(Integer.parseInt(this.docType)).getDescription())));																		
						return "failure";
					}
				}
				

				
				if(this.docType.equals("")) return "failure";
	
				Documents doc = new Documents();
				
				DocumentInstance documentInstance = this.getModelFacade()
						.findDocumentInstanceByCode(Integer
								.parseInt(this.docType));
				
				DocumentStatus ds = new DocumentStatus();
				ds = this.getModelFacade().findDocumentStatus(6);
				
				Person personSigned = (Person)sessionMap.get("person");
				String tempTitle = documentInstance.getDescription();
				doc.setTitle(tempTitle.replace(' ', '_')
					.replace(",_", "_").replace('-', '_')
					.replace(':', '_').replace('\'', '_'));
				
				doc.setPhysicalType("pdf");
				doc.setDocumentInstance(documentInstance);
				doc.setReceivedDateTime(DateUtil.getCurrentDate());
				doc.setStatus(ds);
				doc.setPerson(personSigned);
				CaseRecord cr = this.getModelFacade().findCaseRecordById(
						caseRecordUuid, courtUuid);
				doc.setCaseRecord(cr);
				
				this.getModelFacade().makePersistent(doc);
				doc.setContent(null,fileBytes);
			
				List<Documents> listOfDoc = new ArrayList<Documents>();
				listOfDoc = this.getModelFacade().findDocumentsByCaseUuid(
						caseRecordUuid);
			
				this.getModelFacade().addCaseRecordHistory(caseRecordUuid, Constants.CaseRecordEventType.FILING_CREATED_BY_LEGAL_PREPARER, personSigned,court.getUuid(), "");
				cr.getFiler().add(personSigned);
				
				
				// This is for revmods
				if(documentInstance.getDocumentType().getCode() == Constants.DocumentType.REVIEW_MODIFICATION
					&& this.getCr().getCourt().getUuid().equals("courtUuidClarke"))						
				{
					// move witness to defendent			
					for(PersonParticipants pp : this.getCr().getPersonParticipants())
					{
						if(pp.getRelationship().getCode() == Constants.ParticipantRelationship.Witness)
						{
							pp.setRelationship(
									this.getModelFacade().findParticipantRelationship(Constants.ParticipantRelationship.DefendantParty));
							this.getModelFacade().addCaseRecordHistory(
									caseRecordUuid, 
									Constants.CaseRecordEventType.COOPERATING_PARTY_MOVED_AS_DEFENDANT, 
									personSigned,
									court.getUuid(), "");
							this.getModelFacade().getSession().saveOrUpdate(pp);				
						}
					}
				}
								
				returnStr = "upload";
			}
			// not a pdf file
			else {
				FacesContext facesContext = this.getFacesContext();
				facesContext
						.addMessage(
								"uploadForm:uploadFile",
								new FacesMessage(
										"A text file has been already uploaded. Please upload a pdf file if there's any. "));
				
				//setLockUploadProcess(false);
				LOG.error("Text file already uploaded");
				returnStr = "failure";
			}
		}
		// no case record has been created yet.
		return returnStr;
	}

	/**
	 * This method navigates user to the Case Details Page
	 * 
	 * @return String
	 */
	public String gotoCaseDetailsPage() {
		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		sessionMap.put("from", "establishmentFilingPage");
		
		return "gotoCaseDetailsPage";
	}

	public String retrieveFilingsForExternalCaseNumber() {
		return "goToSearchPage";
	}

	public String uploadPackage() throws Exception {

		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		String caseRecordUuid = (String) sessionMap.get("caseUuid");
		// case record already created
		
		if(this.packageType.equals("")) return "failure";
		
		DocumentPackage docPackage = this.getModelFacade().findPackageNameByUuid(this.packageType);
		Person personSigned = (Person) sessionMap.get("person");
		
		try {
			UploadPackageUtility.uploadPackage(this.getCourt(),
					caseRecordUuid,
					packageDoc,
					docPackage,
					personSigned,
					this.getUploadedDocumentList(),
					this.getModelFacade());
			
			
			FacesContext facesContext = this.getFacesContext();
			facesContext.addMessage("uploadPackageForm:uploadPack",
					new FacesMessage(" Package is Uploaded"));

		}catch(UploadPackageException exn)
		{
			FacesContext facesContext = FacesContext.getCurrentInstance();
			facesContext.addMessage("uploadPackageForm:uploadPack", new FacesMessage("Error: " + exn.getMessage()));			
		}catch(Exception exn)
		{
			FacesContext facesContext = FacesContext.getCurrentInstance();
			facesContext.addMessage("uploadPackageForm:uploadPack", new FacesMessage("Error: " + exn.getMessage()));
			exn.printStackTrace();			
		}
		//HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().commit();
				
		return "upload";
	}

	public String ViewUploadedFileInformation() {
		this.documentList = this.getModelFacade().findDocumentsByDocStatusCode(
				6);
		documentsModel = new ListDataModel();
		documentsModel.setWrappedData(documentList);
		return "viewUploadedFileInformation";
	}

	public void viewListOfUploadedFiles() {
		// To avoid duplicate additions to arrays, reinitialize with each call.
		uploadedDocumentList = new ArrayList<Documents>();
		documentList = new ArrayList<Documents>();
		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		String uuid = (String) sessionMap.get("caseUuid");
		this.documentList = this.getModelFacade().findDocumentsByCaseUuid(uuid);
		for (Documents doc : documentList) {
			if (doc.getStatus().getDescription().equalsIgnoreCase("upload")) {
				LOG.info("Adding the document " + doc.getTitle()
						+ " to the uploaded dcoument list");
				this.uploadedDocumentList.add(doc);

			}
		}
	}

	/**
	 * @return the uploadedDocumentList
	 */
	public List<Documents> getUploadedDocumentList() {
		// To avoid duplicate additions to array, reinitialize with each call.
		uploadedDocumentList = new ArrayList<Documents>();
		documentList = new ArrayList<Documents>();
		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		String uuid = (String) sessionMap.get("caseUuid");
		if (uuid != null) {
			List<Documents> documentList = this.getModelFacade()
					.findDocumentsByCaseUuid(uuid);
			for (Documents doc : documentList) {
				int docStatusCode = doc.getStatus().getCode();
				if (docStatusCode == Constants.DocumentStatus.UPLOAD  
					|| 
					docStatusCode == Constants.DocumentStatus.SIGNED_BY_CLERK  
					|| 
					docStatusCode == Constants.DocumentStatus.SIGNED_BY_ATTORNEY   
					|| 
					docStatusCode == Constants.DocumentStatus.FAILED_ATTORNEY_SIGNATURE 
					||
					docStatusCode == Constants.DocumentStatus.FAILED_TO_IMPORT					
					|| 
					docStatusCode == Constants.DocumentStatus.REJECTED
				) {
					this.uploadedDocumentList.add(doc);
				}
			}
		}
		return uploadedDocumentList;
	}

	/**
	 * @param uploadedDocumentList
	 *            the uploadedDocumentList to set
	 */
	public void setUploadedDocumentList(List<Documents> uploadedDocumentList) {
		this.uploadedDocumentList = uploadedDocumentList;
	}
	
	public String viewFile() {
		FacesContext context = this.getFacesContext();
		HttpServletResponse resp = (HttpServletResponse) FacesContext
				.getCurrentInstance().getExternalContext().getResponse();
		Documents doc = (Documents) this.getDocumentClicked().getValue();
		String docTitle = (String) doc.getTitle();
		byte[] docContent = doc.getContent();
		
		String ret = "stay";
		
		try {
			ret = FileUtility.streamReportToBrowser(resp, docTitle, docContent);
		} catch (IOException e) {
			LOG.error("Error in FilingDataUploadPage.viewFile() method: " + e);
		}
		if(ret.equals("stay")) context.responseComplete();
		return ret;
	}

	public String reviewOfFiling() {
		LOG.info("Inside the reviewOfFiling method....");
		
		return "reviewOfFiling";
	}



	public CaseRecord getCr() {
		return cr;
	}

	public void setCr(CaseRecord cr) {
		this.cr = cr;
	}

	public List<Documents> getNewUploadedDocumentList() {
		return newUploadedDocumentList;
	}

	public void setNewUploadedDocumentList(
			List<Documents> newUploadedDocumentList) {
		this.newUploadedDocumentList = newUploadedDocumentList;
	}

	public UIParameter getCaseDetailsPage() {
		return caseDetailsPage;
	}

	public void setCaseDetailsPage(UIParameter caseDetailsPage) {
		this.caseDetailsPage = caseDetailsPage;
	}

	public DataModel getEstablishmentFilingModel() {
		return establishmentFilingModel;
	}

	public void setEstablishmentFilingModel(DataModel establishmentFilingModel) {
		this.establishmentFilingModel = establishmentFilingModel;
	}

	public Filing getFiling() {
		return filing;
	}

	public void setFiling(Filing filing) {
		this.filing = filing;
	}

	public String deleteDocument() {
		LOG.info("Inside the deleteDocument..");
		/* ********************************************************
		 * TODO - Important - Need to make sure that delete of 
		 * persons does not delete persons that are present in 
		 * other cases.
		 * ******************************************************
		 */
		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		Documents doc = (Documents) this.getDocumentClicked().getValue();
		CaseRecord cr = this.getCr();
		String extention = doc.getPhysicalType();
		if (extention.equalsIgnoreCase("text")) {
			List<PersonParticipants> ppList = this.getModelFacade()
					.getPersonParicipant(cr);
			for (PersonParticipants pp : ppList) {
				
				Person personParticipant = (Person) this.getModelFacade()
						.findPersonbyID(pp.getPerson().getUuid());
				List<CaseRecord> crList = this.getModelFacade()
						.findCaseRecordsByPerson(personParticipant);
				LOG.info("List of related case Records for the PP "
						+ crList.size());
				
				this.getModelFacade().deletePersonParticipants(pp);
				
				/*List<PersonParticipants> ppPList = this.getModelFacade().getPersonParticipantByPerson(personParticipant);
				
				if(ppPList.size() == 0) 
				{	
					this.getModelFacade().deletePerson(personParticipant);
				}else{
					boolean delete = true;
					// if the person is associated with an alternate case,
					// then don't delete.
					for(PersonParticipants xpp : ppPList)
					{
						for(CaseRecord xcr : this.getModelFacade().findCaseRecordsByPerson(xpp.getPerson()))
						{
							if(! xcr.getUuid().equalsIgnoreCase(cr.getUuid()))
							{
								delete = false;
							}
						}
					}
					
					if(delete)
					{
						this.getModelFacade().deletePerson(pp.getPerson());
					}
					
				}
				*/
				if ((personParticipant.getRoles().isEmpty())
						&& (crList.size() <= 1)) {
					//this.getModelFacade().deletePerson(pp.getPerson());

				} else {
					
				}
			}
			this.getModelFacade().deleteCaseRecord(this.getCr().getUuid(), courtUuid);
			sessionMap.remove("caseUuid");
		}

		this.getModelFacade().enableDocDeleteFlag(doc);
		this.getModelFacade().deleteDocument(doc);
		
		return "upload";
	}

	public String back() {
		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		sessionMap.remove("caseUuid");
		return "back";
	}

	public boolean isRenderReviewBtn() {
		return renderReviewBtn;
	}

	public void setRenderReviewBtn(boolean renderReviewBtn) {
		this.renderReviewBtn = renderReviewBtn;
	}

	public boolean validateAttorney(Person personAttorney) {
		// Attorney attorney = this.getModelFacade().
		return false;
	}

	public boolean isRenderListOfPersonsBtn() {
		return renderListOfPersonsBtn;
	}

	public void setRenderListOfPersonsBtn(boolean renderListOfPersonsBtn) {
		this.renderListOfPersonsBtn = renderListOfPersonsBtn;
	}

	public List<Person> getPersonsExtractedFromTextList() {
		return personsExtractedFromTextList;
	}

	public void setPersonsExtractedFromTextList(
			List<Person> personsExtractedFromTextList) {
		this.personsExtractedFromTextList = personsExtractedFromTextList;
	}

	public Person getCusPerson() {
		return cusPerson;
	}

	public void setCusPerson(Person cusPerson) {
		this.cusPerson = cusPerson;
	}

	public Person getNonCusPerson() {
		return nonCusPerson;
	}

	public void setNonCusPerson(Person nonCusPerson) {
		this.nonCusPerson = nonCusPerson;
	}
	public PersonAddress getCusPersonAddress() {
		return cusPersonAddress;
	}

	public void setCusPersonAddress(PersonAddress cusPersonAddress) {
		this.cusPersonAddress = cusPersonAddress;
	}
	public PersonAddress getNonCusPersonAddress() {
		return nonCusPersonAddress;
	}

	public void setNonCusPersonAddress(PersonAddress nonCusPersonAddress) {
		this.nonCusPersonAddress = nonCusPersonAddress;
	}
	
	public List<Person> getInitiatingPartyPersonsList() {
		return initiatingPartyPersonsList;
	}

	public void setInitiatingPartyPersonsList(
			List<Person> initiatingPartyPersonsList) {
		this.initiatingPartyPersonsList = initiatingPartyPersonsList;
	}

	public List<PersonAddress> getInitiatingPartyPersonAddresses() {
		return initiatingPartyPersonAddresses;
	}

	public void setInitiatingPartyPersonAddresses(
			List<PersonAddress> initiatingPartyPersonAddresses) {
		this.initiatingPartyPersonAddresses = initiatingPartyPersonAddresses;
	}

	/**
	 * 
	 * @param documentInstance
	 * @param newFile
	 * @param caseRecordUuid
	 * @param personSigned
	 * @throws IOException
	 */

	/*
		Function never called and replaced by utility class.

	private void splitPDFPackage(DocumentPackage documentPackage, File newFile,
			String caseRecordUuid, Person personSigned) throws IOException {

		DocumentStatus ds = new DocumentStatus();
		ds = this.getModelFacade().findDocumentStatus(6);

		// Pull List of Documents and Page Ranges from DB
		List<DocPageRange> dprList = this.getModelFacade()
				.findAllPageRangeByPackageUuid(documentPackage);

		Map sessionMap = this.getFacesContext().getExternalContext()
				.getSessionMap();
		Court c = (Court) sessionMap.get("court");

		List<DocPageRange> dprUpdatedList;
		ByteArrayOutputStream[] baosArray;
		if(c.getUuid().equalsIgnoreCase("courtUuid5"))
		{
			*
			 * Check the document for dynamically set page range indicators.
			 * 
			 * If present, over ride page ranges from the database. If not present,
			 * then leave list of documents and page ranges unchanged.
			 *
			PageRangesFromTextTargetsUtility targetBasedRangeChecker =
				new PageRangesFromTextTargetsUtility();
	
			// Convert file to Byte Array
			FileInputStream fis = FileUtility.convertFileToInputStream(newFile);
	
			dprUpdatedList = targetBasedRangeChecker
					.pageRangesFromTargetsCheck(fis, dprList);
			for (DocPageRange dpr : dprUpdatedList) {
						Hibernate.initialize(dpr.getDocumentInstance());
			}
	
			SplitPDF sp = new SplitPDF();
			baosArray = sp.SplitFile("/srv/temp/"
					+ newFile.getName(), dprUpdatedList);
			
		}else{
			dprUpdatedList = dprList;
			SplitPDF sp = new SplitPDF();
			baosArray = sp.SplitFile("/srv/temp/"
				+ newFile.getName(), dprList);
		}

		
		int i = 0;
		for (DocPageRange dn : dprUpdatedList) {
			Documents tempDoc = new Documents();
			DocumentInstance docInstance = new DocumentInstance();
			docInstance = dn.getDocumentInstance();
			
			String fileTitle = (dn.getDocumentInstance().getDescription()
					.toString().replace(' ', '_').replace("-", "_").replace(
							",_", "_").replace(':', '_').replace('\'', '_'));

			tempDoc.setTitle(fileTitle);
			tempDoc.setPhysicalType("pdf");
			CaseRecord cr = this.getModelFacade().findCaseRecordById(
					caseRecordUuid, courtUuid);
			tempDoc.setCaseRecord(cr);
			tempDoc.setDocumentInstance(docInstance);
			tempDoc.setPerson(personSigned);
			tempDoc.setReceivedDateTime(DateUtil.getCurrentDate());
			tempDoc.setStatus(ds);

			this.getModelFacade().makePersistent(tempDoc);
			
			byte[] docContent = baosArray[i].toByteArray();
			tempDoc.setContent(docContent);
			
			i++;
		}
	}
	*/
	
	public String getExternalCaseRecordNumber() {
		return this.externalCaseRecordNumber;
	}

	public void setExternalCaseRecordNumber(String externalCaseRecordNumber) {
		this.externalCaseRecordNumber = externalCaseRecordNumber;
	}

	public String getCusSSN() {
		return cusSSN;
	}

	public void setCusSSN(String cusSSN) {
		this.cusSSN = cusSSN;
	}

	public String getNonCusSSNHashed() {
		return nonCusSSN;
	}

	public void setNonCusSSNHashed(String nonCusSSNHashed) {
		this.nonCusSSN = nonCusSSNHashed;
	}

	public List<String> getInitiatingPartyPersonSSNList() {
		return initiatingPartyPersonSSNList;
	}

	public void setInitiatingPartyPersonSSNList(
			List<String> initiatingPartyPersonSSNList) {
		this.initiatingPartyPersonSSNList = initiatingPartyPersonSSNList;
	}

	/**
	 * @return the cusAddress
	 */
	public Address getCusAddress() {
		return cusAddress;
	}

	/**
	 * @param cusAddress the cusAddress to set
	 */
	public void setCusAddress(Address cusAddress) {
		this.cusAddress = cusAddress;
	}

	/**
	 * @return the nonCusAddress
	 */
	public Address getNonCusAddress() {
		return nonCusAddress;
	}

	/**
	 * @param nonCusAddress the nonCusAddress to set
	 */
	public void setNonCusAddress(Address nonCusAddress) {
		this.nonCusAddress = nonCusAddress;
	}
	
	public boolean isAsExhibit() {
		return asExhibit;
	}

	public void setAsExhibit(boolean asExhibit) {
		this.asExhibit = asExhibit;
	}
	
	/**
	 * 
	 * @return true or false
	 */
	public boolean isContempt() {
		return contempt;
	}
	
	/**
	 * 
	 * @param contempt
	 */
	public void setContempt(boolean contempt) {
		this.contempt = contempt;
	}
	
	/**
	 * 
	 * @return civil action number
	 */
	public String getCvNumber() {
		return cvNumber;
	}
	
	/**
	 * 
	 * @param cvNumber
	 */
	public void setCvNumber(String cvNumber) {
		this.cvNumber = cvNumber;
	}
}